<template>
  <el-card>
    <div class="card-header">
      <span>部门管理</span>
    </div>
  </el-card>
  <el-card class="content">
    <el-form-item>
      <perms-button
          perms="privilege:department:list"
          :type="Types.primary"
          :plain="true"
          @action="list"/>
    </el-form-item>
    <el-table
        v-if="tableVisible"
        :data="departmentList"
        :border="true"
        row-key="id"
        :default-expand-all="expand"
        :tree-props="{ children: 'children', hasChildren: '!!children' }"
    >
      <template #empty>
        <el-empty/>
      </template>
      <el-table-column label="">
        <template #header>
          <perms-button
              perms="privilege:department:add"
              :type="Types.primary"
              :size="Sizes.default"
              :plain="true"
              @action="addDepartment"/>
          <el-button @click="switchExpand(true)" size="default">展开全部</el-button>
          <el-button @click="switchExpand(false)" size="default">折叠全部</el-button>
        </template>
        <el-table-column prop="name" label="部门名称"/>
        <el-table-column prop="code" label="部门编码" width="200"/>
        <el-table-column prop="full_name" label="部门全称" min-width="300"/>
        <el-table-column prop="sort_id" label="排序" width="80" align="center"/>
        <el-table-column prop="type" label="类型" width="90" align="center">
          <template #default="scope">
            <el-tag size="small" :type="typeType(scope.row.type)">{{ typeText(scope.row.type) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template #default="scope">
            <perms-link
                v-if="scope.row.type>=10"
                perms="privilege:department:add"
                :type="Types.primary"
                :plain="true"
                @action="addSubDepartment(scope.row)"/>
            <perms-link
                v-if="scope.row.type<40"
                perms="privilege:department:update"
                :type="Types.warning"
                :plain="true"
                @action="editDepartment(scope.row)"/>
            <el-popconfirm
                :title="`确定删除部门[${scope.row.name}]吗?`"
                :icon="InfoFilled"
                icon-color="#F56C6C"
                cancel-button-text="取消"
                confirm-button-text="确认删除"
                cancel-button-type="info"
                confirm-button-type="danger"
                @confirm="deleteDepartment(scope.row.id)"
                width="300"
            >
              <template #reference>
                <perms-link
                    perms="privilege:department:delete"
                    :type="Types.danger"
                    :plain="true"/>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>

      </el-table-column>
    </el-table>
  </el-card>
  <el-dialog
      v-model="visible"
      :title="title"
      :key="new Date().getTime()"
      draggable
      width="800"
      :close-on-click-modal="false"
      @close="handleClose"
  >
    <el-form ref="formRef" :model="departmentForm" :rules="rules" label-width="100">
      <el-form-item label="部门类型" prop="type">
        <el-radio-group v-model.number="departmentForm.type" :disabled="action==='editDepartment'">
          <el-radio :label="40">公司</el-radio>
          <el-radio :label="30">子公司</el-radio>
          <el-radio :label="20">部门</el-radio>
          <el-radio :label="10">小组</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="上级部门" prop="parent_id">
        <el-cascader
            :options="options"
            :props="props"
            v-model="cascaderParent"
            ref="parentRef"
            clearable
            style="width: 360px">
          <template #default="{ node, data }">
            <span>{{ data.name }}</span>
            <span v-if="!node.isLeaf"> ({{ !!data.children ? data.children.length : 0 }}) </span>
          </template>
        </el-cascader>
      </el-form-item>
      <el-row>
        <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
          <el-form-item label="部门名称" prop="name">
            <el-input v-model="departmentForm.name" style="width: 360px" placeholder="例如：部门名称"/>
          </el-form-item>
          <el-form-item label="部门编码" prop="code">
            <el-input v-model="departmentForm.code" style="width: 360px"/>
          </el-form-item>
        </el-col>
        <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
          <el-form-item label="部门全称" prop="full_name">
            <el-input v-model="departmentForm.full_name" style="width: 360px"/>
          </el-form-item>
          <el-form-item label="部门排序" prop="sort_id">
            <el-input v-model.number="departmentForm.sort_id" style="width: 360px"/>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        </el-col>
        <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        </el-col>
      </el-row>
      <el-form-item label="备注" prop="remark">
        <el-input type="textarea" v-model="departmentForm.remark" rows="5" placeholder="请输入备注"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="handleClose">取消</el-button>
      <el-button type="primary" plain @click="handleSubmit">提交</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
//部门列表表单
import {nextTick, onMounted, reactive, ref} from "vue";
import {Department} from "@/interface/department";
import {DepartmentAddR, DepartmentListR, DepartmentRemoveR, DepartmentUpdateR} from "@/api/department";
import {CascaderInstance, ElMessage, FormInstance, FormRules} from "element-plus";
import Node from "element-plus/es/components/cascader-panel/src/node";
import {InfoFilled} from "@element-plus/icons-vue";
import {LoadDepartmentTree} from "@/utils/department";
import {Sizes, Types} from "@/interface/enum";
import PermsButton from '@/components/PermsButton.vue'
import PermsLink from '@/components/PermsLink.vue'
import {DeleteRequest} from "@/interface/user";


const initDepartmentForm = () => {
  return <Department>{
    id: 0,
    type: 20, //部门类型：10.小组，20.部门，30.子公司，40.公司
    sort_id: 1,
    parent_id: 0,
    name: '',
    full_name: '',
    code: '',
    remark: '',
  }
}

//级联选择器
const options = ref<Department[]>()
const props = ref({label: 'name', value: 'id', checkStrictly: true})

const departmentForm = ref<Department>(initDepartmentForm())
const icon = ref<string>('search')
//表单校验
const formRef = ref<FormInstance>()
const parentRef = ref<CascaderInstance>()

//表格展开属性
const expand = ref<boolean>(true)
const tableVisible = ref<boolean>(true)

const departmentList = ref<Department[]>()
//dialog可见
const visible = ref<boolean>(false)
const title = ref<string>('')
const action = ref<string>('') //表单动作：addDepartment，新增部门； addSubDepartment，新增子部门； editDepartment，修改部门

//校验上级部门
const parentValidator = (rule: any, value: any, callback: any) => {
  //设置parent_id
  let nodes = parentRef.value?.getCheckedNodes(false) //是否只监测leaf节点
  if (!!nodes && nodes.length > 0) {
    departmentForm.value.parent_id = (nodes.pop() as Node).value as number
  } else {
    departmentForm.value.parent_id = 0
  }

  if (departmentForm.value.parent_id < 1) {
    callback(new Error('必选'))
  } else {
    callback()
  }
}

const rules = reactive<FormRules>({
  parent_id: [
    {required: true, message: '必选', validator:parentValidator, trigger: ['blur', 'change']}
  ],
  type: [
    {required: true, message: '请选择指定的部门类型', type: "enum", enum: [10, 20, 30, 40], trigger: ['blur', 'change']},
  ],
  name: [
    {required: true, message: '必填', type: "string", trigger: ['blur', 'change']}
  ],
  full_name: [
    {required: true, message: '必填', type: "string", trigger: ['blur', 'change']}
  ],
  code: [
    {required: true, message: '必填', type: "string", trigger: ['blur', 'change']}
  ],
  sort_id: [
    {required: true, message: '必填', type: "number", trigger: ['blur', 'change']}
  ],
})

const list = () => {
  DepartmentListR().then(res => res.data).then(res => {
    switch (res.code) {
      case 200:
        //部门列表=>部门树
        let departments = res.data as Department[]
        let parents = departments.filter((m) => m.parent_id === 0)
        let children = departments.filter((m) => m.parent_id !== 0)

        LoadDepartmentTree(parents, children)

        departmentList.value = parents

        // let department: Department = initDepartmentForm()
        // department.name = '全部'
        // department.children = parents
        // options.value = [department]
        options.value = parents

        parentIds.value = new Map<number, Array<number>>()
        loadParentIds(parents)
        break
      default:
        //ElMessage.error(res.msg)
    }
  })
}

//部门展开
const switchExpand = (val: boolean) => {
  tableVisible.value = false
  expand.value = val

  nextTick(() => {
    tableVisible.value = true
  })
}

const typeText = (val: number) => {
  switch (val) {
    case 10:
      return '小组'
    case 20:
      return '部门'
    case 30:
      return '子公司'
    case 40:
      return '公司'
    default:
      console.log('未知部门类型：', val)
      return '未知'
  }
}

const typeType = (val: number) => {
  switch (val) {
    case 10:
      return 'danger'
    case 20:
      return 'warning'
    case 30:
      return ''
    case 40:
      return 'success'
    default:
      return 'info'
  }
}


//获取部门节点的完整级联路径
const parentIds = ref<Map<number, Array<number>>>(new Map<number, Array<number>>())
const cascaderParent = ref<Array<number>>([])
const loadParentIds = (departments: Department[]) => {
  departments.forEach((department) => {
    //查询上级级部门的路径
    let parentId: Array<number> = []
    if (!parentIds.value.has(department.parent_id)) {
      parentIds.value.set(department.parent_id, [])
    }

    parentId = parentIds.value.get(department.parent_id) as Array<number>
    if(department.parent_id>0){
      parentIds.value.set(department.id, [...parentId, department.parent_id])
    }else{
      parentIds.value.set(department.id, [...parentId])
    }
    // console.log('[id]', department.id, '=>[parent_id]', department.parent_id, '=> [path]', JSON.stringify(parentIds.value.get(department.id)))

    if (!!department.children && department.children.length > 0) {
      loadParentIds(department.children)
    }
  })
}


//添加部门
const addDepartment = () => {
  visible.value = true
  title.value = '新增部门'
  action.value = 'addDepartment'
  departmentForm.value = initDepartmentForm()
}


//添加子部门
const addSubDepartment = (parent: Department) => {
  title.value = '新增部门'
  action.value = 'addSubDepartment'
  visible.value = true
  departmentForm.value = initDepartmentForm()
  departmentForm.value.parent_id = parent.id
  cascaderParent.value = [...parentIds.value.get(parent.id) as Array<number>, parent.id]
}

//修改部门
const editDepartment = (department: Department) => {
  title.value = '修改部门'
  action.value = 'editDepartment'
  visible.value = true
  departmentForm.value = Object.assign((department)) //对象浅拷贝
  cascaderParent.value = parentIds.value.get(department.id) as Array<number>
}

//提交表单
const handleSubmit = () => {
  //设置parent_id
  let nodes = parentRef.value?.getCheckedNodes(false) //是否只监测leaf节点
  if (!!nodes && nodes.length > 0) {
    departmentForm.value.parent_id = (nodes.pop() as Node).value as number
  } else {
    departmentForm.value.parent_id = 0
  }

  //表单校验
  formRef.value?.validate((isValid) => {
    if (!isValid) {
      return
    }

    switch (action.value) {
      case 'addDepartment':
        DepartmentAddR(departmentForm.value).then(res => res.data).then((res) => {
          switch (res.code) {
            case 200:
              handleClose()
              list()
              break
            default:
          }
        })
        break
      case 'addSubDepartment':
        DepartmentAddR(departmentForm.value).then(res => res.data).then(res => {
          switch (res.code) {
            case 200:
              handleClose()
              list()
              break
            default:
          }
        })
        break
      case 'editDepartment':
        DepartmentUpdateR(departmentForm.value).then(res => res.data).then(res => {
          switch (res.code) {
            case 200:
              ElMessage.success(res.msg)
              handleClose()
              list()
              break
            default:
          }
        }).catch(err => {
          ElMessage.error(err.toString())
        })
        break
      default:
        ElMessage.warning('未知操作')
    }
  })
}

//删除部门
const deleteDepartment = (id: number) => {
  let req = <DeleteRequest>{id: id}
  DepartmentRemoveR(req).then(res => res.data).then(res => {
    switch (res.code) {
      case 200:
        ElMessage.success(res.msg)
        list()
        break
      default:

    }
  })
}

//关闭表单
const handleClose = () => {
  visible.value = false
  // formRef.value?.resetFields()
  departmentForm.value = initDepartmentForm()
}



onMounted(() => {
  list()
})

</script>

<style scoped lang="less">
.el-card {
  margin-bottom: 10px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.page {
  margin-top: 10px;
}

.links {
  padding-right: 10px;
}

//图标气泡卡片
.icon-popper {
  max-height: 500px;
}

.icon-content {
  max-height: 450px;
  overflow: auto;
  overflow-x: hidden;
}
</style>